package commands;

import user.User;
import messages.InvalidInvitationReceivedMessage;
import messages.InvitationMessage;
import messages.Message;
import core.GameManager;
import core.Invitation;
import core.UserManager;
import event.InvalidInvitationReceivedEventArgs;
import event.InvitationReceivedEventArgs;


/**
 * The Invite command.
 * 
 * This command will handle Invite messages.
 */
public class InvitationCommand extends Command {
	
	public InvitationCommand(Message message, User user) {
		super(message, user);
	}
	
	
	@Override
	public void execute() {
		GameManager gameManager = this.controller.getGameManager();
		UserManager userManager = controller.getUserManager();
		InvitationMessage message = (InvitationMessage) this.message;
		message.setOriginLogin(this.user.getLogin());
		
		synchronized(userManager) {
			synchronized(gameManager) {
				
				// Is the invited user online and does the game exist?
				if (userManager.isLoggedIn(message.getDestinyLogin()) && 
						gameManager.containsGame(message.getGameName())) {	
			
					// Creates a new invitation and adds it to the game manager
					Invitation invitation = new Invitation(this.user.getPlayer(), 
							userManager.getPlayer(message.getDestinyLogin()), message.getGameName());
					gameManager.addInvitation(invitation);
					
					// Sets the reply-id: the identifier the destiny must include in the reply message
					// in order to identify the invitation.
					message.setReplyId(invitation.getId());
					
					// Fires the InvitationReceived event.
					this.controller.fireInvitationReceivedEvent(new InvitationReceivedEventArgs(message));
				} else {
					InvalidInvitationReceivedMessage invalidMessage;
					
					if (!userManager.isLoggedIn(message.getDestinyLogin()))
						invalidMessage = new InvalidInvitationReceivedMessage(message, InvalidInvitationReceivedMessage.ErrorCode.UnknownUser);
					else 
						invalidMessage = new InvalidInvitationReceivedMessage(message, InvalidInvitationReceivedMessage.ErrorCode.UnknownGame);						
					
					this.controller.fireInvalidInvitationReceivedEvent(new InvalidInvitationReceivedEventArgs(invalidMessage));
				}
			}
		}
	}
}
